home *** CD-ROM | disk | FTP | other *** search
- import sys, math, audiodev
-
- DOT = 30
- DAH = 80
- OCTAVE = 2 # 1 == 441 Hz, 2 == 882 Hz, ...
- SAMPWIDTH = 2
- FRAMERATE = 44100
- BASEFREQ = 441
- QSIZE = 20000
-
- morsetab = {
- 'A': '.-', 'a': '.-',
- 'B': '-...', 'b': '-...',
- 'C': '-.-.', 'c': '-.-.',
- 'D': '-..', 'd': '-..',
- 'E': '.', 'e': '.',
- 'F': '..-.', 'f': '..-.',
- 'G': '--.', 'g': '--.',
- 'H': '....', 'h': '....',
- 'I': '..', 'i': '..',
- 'J': '.---', 'j': '.---',
- 'K': '-.-', 'k': '-.-',
- 'L': '.-..', 'l': '.-..',
- 'M': '--', 'm': '--',
- 'N': '-.', 'n': '-.',
- 'O': '---', 'o': '---',
- 'P': '.--.', 'p': '.--.',
- 'Q': '--.-', 'q': '--.-',
- 'R': '.-.', 'r': '.-.',
- 'S': '...', 's': '...',
- 'T': '-', 't': '-',
- 'U': '..-', 'u': '..-',
- 'V': '...-', 'v': '...-',
- 'W': '.--', 'w': '.--',
- 'X': '-..-', 'x': '-..-',
- 'Y': '-.--', 'y': '-.--',
- 'Z': '--..', 'z': '--..',
- '0': '-----',
- '1': '.----',
- '2': '..---',
- '3': '...--',
- '4': '....-',
- '5': '.....',
- '6': '-....',
- '7': '--...',
- '8': '---..',
- '9': '----.',
- ',': '--..--',
- '.': '.-.-.-',
- '?': '..--..',
- ';': '-.-.-.',
- ':': '---...',
- "'": '.----.',
- '-': '-....-',
- '/': '-..-.',
- '(': '-.--.-',
- ')': '-.--.-',
- '_': '..--.-',
- ' ': ' '
- }
-
- # If we play at 44.1 kHz (which we do), then if we produce one sine
- # wave in 100 samples, we get a tone of 441 Hz. If we produce two
- # sine waves in these 100 samples, we get a tone of 882 Hz. 882 Hz
- # appears to be a nice one for playing morse code.
- def mkwave(octave):
- global sinewave, nowave
- sinewave = ''
- n = int(FRAMERATE / BASEFREQ)
- for i in range(n):
- val = int(math.sin(2 * math.pi * i * octave / n) * 0x7fff)
- sample = chr((val >> 8) & 255) + chr(val & 255)
- sinewave = sinewave + sample[:SAMPWIDTH]
- nowave = '\0' * (n*SAMPWIDTH)
-
- mkwave(OCTAVE)
-
- class BufferedAudioDev:
- def __init__(self, *args):
- import audiodev
- self._base = apply(audiodev.AudioDev, args)
- self._buffer = []
- self._filled = 0
- self._addmethods(self._base, self._base.__class__)
- def _addmethods(self, inst, cls):
- for name in cls.__dict__.keys():
- if not hasattr(self, name):
- try:
- setattr(self, name, getattr(inst, name))
- except:
- pass
- for basecls in cls.__bases__:
- self._addmethods(self, inst, basecls)
- def writeframesraw(self, frames):
- self._buffer.append(frames)
- self._filled = self._filled + len(frames)
- if self._filled >= QSIZE:
- self.flush()
- def wait(self):
- self.flush()
- self._base.wait()
- def flush(self):
- print 'flush: %d blocks, %d bytes' % (len(self._buffer), self._filled)
- if self._buffer:
- import string
- self._base.writeframes(string.joinfields(self._buffer, ''))
- self._buffer = []
- self._filled = 0
-
- def main(args = sys.argv[1:]):
- import getopt, string
- try:
- opts, args = getopt.getopt(args, 'o:p:')
- except getopt.error:
- sys.stderr.write('Usage ' + sys.argv[0] +
- ' [ -o outfile ] [ args ] ...\n')
- sys.exit(1)
- dev = None
- for o, a in opts:
- if o == '-o':
- import aifc
- dev = aifc.open(a, 'w')
- dev.setframerate(FRAMERATE)
- dev.setsampwidth(SAMPWIDTH)
- dev.setnchannels(1)
- if o == '-p':
- mkwave(string.atoi(a))
- if not dev:
- dev = BufferedAudioDev()
- dev.setoutrate(FRAMERATE)
- dev.setsampwidth(SAMPWIDTH)
- dev.setnchannels(1)
- dev.close = dev.stop
- if args:
- line = string.join(args)
- else:
- line = sys.stdin.readline()
- while line:
- print line
- mline = morse(line)
- print mline
- play(mline, dev)
- if hasattr(dev, 'wait'):
- dev.wait()
- if not args:
- line = sys.stdin.readline()
- else:
- line = ''
- dev.close()
-
- # Convert a string to morse code with \001 between the characters in
- # the string.
- def morse(line):
- res = ''
- for c in line:
- try:
- res = res + morsetab[c] + '\001'
- except KeyError:
- pass
- return res
-
- # Play a line of morse code.
- def play(line, dev):
- for c in line:
- if c == '.':
- sine(dev, DOT)
- elif c == '-':
- sine(dev, DAH)
- else:
- pause(dev, DAH)
- pause(dev, DOT)
-
- def sine(dev, length):
- dev.writeframesraw(sinewave*length)
-
- def pause(dev, length):
- dev.writeframesraw(nowave*length)
-
- if __name__ == '__main__' or sys.argv[0] == __name__:
- main()
-